package cn.xerllent.wxtp.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageInfo;

import cn.hutool.core.util.ObjectUtil;
import cn.xerllent.common.service.impl.BaseServiceImpl;
import cn.xerllent.wxtp.entity.WxAdmin;
import cn.xerllent.wxtp.entity.WxCorp;
import cn.xerllent.wxtp.entity.WxDepartment;
import cn.xerllent.wxtp.entity.WxUser;
import cn.xerllent.wxtp.service.WxCorpService;
import cn.xerllent.wxtp.service.WxDepartmentService;
import cn.xerllent.wxtp.service.WxUserService;
import cn.xerllent.wxtp.service.mapper.WxDepartmentMapper;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpTpAdmin;
import me.chanjar.weixin.cp.bean.WxCpTpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.tp.service.WxCpTpService;
import cn.xerllent.common.utils.FileUtil;

@Slf4j
@Service
//@AllArgsConstructor
//@CacheConfig(cacheNames = "user")
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class WxDepartmentServiceImpl extends BaseServiceImpl<WxDepartmentMapper, WxDepartment>  implements WxDepartmentService {

	@Resource
	private WxUserService wxUserService;
	
    @Override
    //@Cacheable
    public Map<String, Object> queryAll(WxDepartment filter,Pageable pageable) {
    	pageHelper(pageable);
        PageInfo<WxDepartment> page = new PageInfo<>(queryAll(filter));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("list", page.getList());
        map.put("total", page.getTotal());
        return map;
    }

    @Override
    //@Cacheable
    public List<WxDepartment> queryAll(WxDepartment filter) {
    	//方法1
    	QueryWrapper<WxDepartment> querywrapper = new QueryWrapper<>();
    	if(ObjectUtil.isNotEmpty(filter)) {
        	if(ObjectUtil.isNotEmpty(filter.getCorpId())) {
        		querywrapper.eq("corp_id", filter.getCorpId());
        	}
        	if(ObjectUtil.isNotEmpty(filter.getParentId())) {
        		querywrapper.eq("parent_id", filter.getParentId());
        	}
        	if(filter.getName()!=null) {
        		querywrapper.like("name", filter.getName());
        	}
        	
        	//querywrapper.last("order by od");  //需要验证
    	}
    	return baseMapper.selectList(querywrapper);
    }

    @Override
    public void download(List<WxDepartment> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (WxDepartment wxDepartment : all) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id",wxDepartment.getId());
            map.put("企业id",wxDepartment.getCorpId());
            map.put("部门id",wxDepartment.getDepartmentId());
            map.put("上级部门id",wxDepartment.getParentId());
            map.put("部门名称",wxDepartment.getName());
            map.put("部门排序",wxDepartment.getOd());
            //map.put("原始数据包",wxDepartment.getWxpackage());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
    
	/**
	 * 同步企业部门列表及用户到本地数据库
	 * @param wxCpTpService 应用api服务
	 * @param corp 企业应用对象
	 * @param withUsers 是否同时更新用户
	 */
	@Override
	public void syncDepartments(final WxCpTpService wxCpTpService, final WxCorp corp,boolean withUsers) {
		//1.获取应用管理员
		try {
			//使用企业api时，先调用此方法:如果没有企业accesstoken则通过api获取并缓存到storage
			wxCpTpService.getCorpToken(corp.getCorpId(), corp.getPermanentCode(),false);
			
			List<WxCpTpDepart> departs = wxCpTpService.getWxCpTpDepartmentService().list(corp.getCorpId());
			
			List<WxDepartment> wxDepartments = departs.stream().map(depart ->{
				WxDepartment d = getOne(new LambdaUpdateWrapper<WxDepartment>().eq(WxDepartment::getCorpId, corp.getCorpId()).eq(WxDepartment::getDepartmentId, depart.getId()));
				if(d==null) { d = new WxDepartment(); }
				return d.setCorpId(corp.getCorpId())
				.setDepartmentId(depart.getId())
				.setParentId(depart.getParentid())
				.setOd(depart.getOrder())
				.setName(depart.getName())
				.setWxpackage(depart.toJson());
				}).collect(Collectors.toList());
			saveOrUpdateBatch(wxDepartments);
			
			//同步用户
			if(withUsers) {
				for(WxDepartment d: wxDepartments) {
					wxUserService.syncDepartmentUsers(wxCpTpService, d);
				}
			}
		
		} catch (WxErrorException e) {
			log.error("syncDepartments err:", e);
		}
	}
    
	/**
	 * 清除对应Mapper的二级缓存，采用无害删除空数据模拟清空,因为二级缓存更新机制是本表数据更新即可清空<br>
	 * 提供本方法供联表更新查询的实时更新
	 * */
	@Override
	public void clearCache() {
		baseMapper.deleteById(0);
	}

}
